package com.eastfair.venueservice.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
//import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.eastfair.boot.request.PageParams;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.pay.dto.TransactionDTO;
import com.eastfair.pay.enums.InvoiceApplyBusinessTypeEnum;
import com.eastfair.pay.enums.TransactionStatusEnum;
import com.eastfair.pay.enums.TranstionTypeEnum;
import com.eastfair.venueservice.dao.BondPayRecordMapper;
import com.eastfair.venueservice.dto.BondManageDTO;
import com.eastfair.venueservice.dto.BondPayRecordDTO;
import com.eastfair.venueservice.dto.BondPayRecordPageQuery;
import com.eastfair.venueservice.entity.BondManage;
import com.eastfair.venueservice.entity.BondPayRecord;
import com.eastfair.venueservice.exceptioncode.VenueServiceExceptionCode;
import com.eastfair.venueservice.service.BondManageService;
import com.eastfair.venueservice.service.BondPayRecordService;
import com.eastfair.venueservice.service.VenueManageExhibitorService;
import com.eastfair.venueservice.service.VenueManageTransactionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 业务实现类
 * 保证金付款记录
 * </p>
 *
 * @author lyw
 * @date 2023-02-17
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class BondPayRecordServiceImpl extends SuperServiceImpl<BondPayRecordMapper, BondPayRecord> implements BondPayRecordService {

    @Resource
    private BondManageService bondManageService;

    @Resource
    private VenueManageExhibitorService venueManageExhibitorService;

    @Resource
    private VenueManageTransactionService venueManageTransactionService;


    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<BondPayRecord> modelList) {
        modelList.forEach(s -> s.setIsDeleted(BusinessConstant.YES));
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(BondPayRecord model) {
        if (model.getPayTime() == null) {
            model.setPayTime(LocalDateTime.now());
        }
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        return R.successDef();
    }

    public void handlerQueryParams(PageParams<BondPayRecordPageQuery> pageParams) {
        if (StrUtil.isBlank(pageParams.getSort()) || StrUtil.isBlank(pageParams.getOrder())) {
            pageParams.setSort("createTime");
            pageParams.setOrder("descending");
        }
    }

    /**
     * 支付保证金
     *
     * @param bondManageDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean payBond(BondManageDTO bondManageDTO) {
        log.info("payBond - 支付保证金, bondManageDTO={}", bondManageDTO);
        List<BondManage> bondManages = bondManageService.listBondManage(bondManageDTO);
        for (BondManage bondManage : bondManages) {
            BondPayRecordDTO bondPayRecordDTO = new BondPayRecordDTO();
            bondPayRecordDTO.setBondId(bondManage.getId());
            bondPayRecordDTO.setPayAmount(bondManageDTO.getPayAmount());
            bondPayRecordDTO.setPayType(bondManageDTO.getPayType());
            return saveBondPayRecordInfo(bondPayRecordDTO);
        }
        return false;
    }

    /**
     * 保存保证金支付记录信息
     *
     * @param bondPayRecordDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveBondPayRecordInfo(BondPayRecordDTO bondPayRecordDTO) {
        log.info("saveBondPayRecordInfo - 保存保证金支付记录信息, bondPayRecordDTO={}", bondPayRecordDTO);
        // 更新保证金订单支付金额
        BondManageDTO bondManageDTO = new BondManageDTO();
        bondManageDTO.setId(bondPayRecordDTO.getBondId());
        bondManageDTO.setPayAmount(bondPayRecordDTO.getPayAmount());
        BondManage bondManage = bondManageService.updatePayAmount(bondManageDTO);
        // 保存支付记录
        BondPayRecord bondPayRecord = BeanUtil.toBean(bondPayRecordDTO, BondPayRecord.class);
        save(bondPayRecord);
        // 保存交易记录
        saveTransaction(bondManage, bondPayRecordDTO);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveForHomeBondManage(BondPayRecordDTO bondPayRecordDTO) {
        log.info("saveForHomeBondManage - 主场保证金保存支付记录, bondPayRecordDTO={}", bondPayRecordDTO);
        saveBondPayRecordInfo(bondPayRecordDTO);
        // 更新展商展位的保证金
        BondManage bondManage = bondManageService.getById(bondPayRecordDTO.getBondId());
        if (Objects.isNull(bondManage)) {
            throw BizException.wrap(VenueServiceExceptionCode.BOND_MANAGE_NOT_EXIST);
        }
        venueManageExhibitorService.updateEarnestMoneyByBondManage(bondManage);
        return true;
    }

    @Override
    public boolean saveTransaction(BondManage bondManage, BondPayRecordDTO bondPayRecordDTO) {
        //保存交易记录
        TransactionDTO transactionDTO = new TransactionDTO();
        transactionDTO.setExhibitionId(bondManage.getExhibitionManageId());
        transactionDTO.setExhibitionName(bondManage.getExhibitionManageName());
        transactionDTO.setSpaceName(bondManage.getSpaceName());
        transactionDTO.setSiteName(bondManage.getSiteName());
        transactionDTO.setServiceProviderId(bondManage.getServiceProviderId());
        transactionDTO.setServiceProviderName(bondManage.getServiceProviderName());
        transactionDTO.setServiceProviderType(bondManage.getServiceProviderType());
        transactionDTO.setOrderType(InvoiceApplyBusinessTypeEnum.BOND_AMOUNT.getCode());
        transactionDTO.setOrderNum(bondManage.getId().toString());
        transactionDTO.setOrderAmount(bondPayRecordDTO.getPayAmount());
        transactionDTO.setOrderTime(LocalDateTime.now());
        transactionDTO.setTransactionType(TranstionTypeEnum.PAYED.getCode());
        transactionDTO.setTransactionState(TransactionStatusEnum.PAYED.getCode());
        transactionDTO.setPayer(bondPayRecordDTO.getPayer());
        transactionDTO.setPayType(bondPayRecordDTO.getPayType());
        transactionDTO.setSystemScene(ContextUtil.getSystemScene());
        venueManageTransactionService.save(transactionDTO);
        return true;
    }

    /**
     * 根据保证金id查询支付记录列表
     *
     * @param bondId
     * @return
     */
    @Override
    public List<BondPayRecord> getBondPayRecordListByBondId(Long bondId) {
        log.info("getBondPayRecordListByBondId - 根据保证金id查询支付记录列表, bondId={}", bondId);
        QueryWrapper<BondPayRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(BondPayRecord::getIsDeleted, BusinessConstant.DELETE_NO)
                .eq(Objects.nonNull(bondId), BondPayRecord::getBondId, bondId);
        return list(queryWrapper);
    }
}
